import React from 'react'
import { ImageSourcePropType } from 'react-native'
import Portal from '../portal'
import ToastContainer from './ToastContainer'

interface IToastConfigurable {
  duration?: number
  source?: ImageSourcePropType
  onClose?: () => void
  mask?: boolean
  stackable?: boolean
}

type IToastProps = string | React.ReactNode

const SHORT = 1.5

const defaultConfig: IToastConfigurable = {
  duration: SHORT,
  onClose: () => {},
  mask: true,
  stackable: true,
}

const toastKeyMap: { [key: number]: 1 } = {}

function remove(key: number) {
  Portal.remove(key)
  delete toastKeyMap[key]
}

function removeAll() {
  Object.keys(toastKeyMap).forEach((_key) => Portal.remove(Number.parseInt(_key, 10)))
}

function notice(
  content: IToastProps,
  type: string,
  config: IToastConfigurable = defaultConfig,
) {
  const props = {
    content: content as string | React.ReactNode,
  }
  Object.assign(props, config)

  if (!config.stackable) {
    removeAll()
  }

  const key = Portal.add(
    <ToastContainer
      content={props.content}
      duration={config.duration}
      onClose={config.onClose}
      source={config.source}
      type={type}
      mask={config.mask}
      onAnimationEnd={() => {
        remove(key)
      }}
    />,
  )
  toastKeyMap[key] = 1
  return key
}

export default {
  SHORT,
  LONG: 8,
  info(props: IToastProps, config?: IToastConfigurable) {
    return notice(props, 'info', config)
  },
  success(props: IToastProps, config?: IToastConfigurable) {
    return notice(props, 'success', config)
  },
  error(props: IToastProps, config?: IToastConfigurable) {
    return notice(props, 'fail', config)
  },
  loading(props: IToastProps, config?: IToastConfigurable) {
    return notice(props, 'loading', config)
  },
  remove,
  removeAll,
}
